/*
 * Copyright 2002-2012 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.aop.framework;

import org.springframework.lang.Nullable;

/**
 * Delegate interface for a configured AOP proxy, allowing for the creation
 * of actual proxy objects.
 *
 * <p>Out-of-the-box implementations are available for JDK dynamic proxies
 * and for CGLIB proxies, as applied by {@link DefaultAopProxyFactory}.
 *
 * @author Rod Johnson
 * @author Juergen Hoeller
 * @see DefaultAopProxyFactory
 */
/*
1. 总结
AopProxy 是 Spring AOP 框架中的核心接口，负责创建实际的代理对象
它定义了两种创建代理对象的方法，支持不同的类加载器配置
主要有两种实现：JDK 动态代理和 CGLIB 代理
通常由 DefaultAopProxyFactory 根据配置选择合适的实现
2. 内部成员解释
Object getProxy(): 使用默认类加载器创建代理对象
Object getProxy(@Nullable ClassLoader classLoader): 使用指定类加载器创建代理对象
3. 类关系结构
AopProxy (interface)
├── JdkDynamicAopProxy (implementation)
└── CglibAopProxy (implementation)
    └── ObjenesisCglibAopProxy (implementation)

	相关类说明:
		DefaultAopProxyFactory: 负责根据配置选择并创建合适的 AopProxy 实现
		JdkDynamicAopProxy: 基于 JDK 动态代理的实现，只能代理实现了接口的类
		CglibAopProxy 及其子类 ObjenesisCglibAopProxy: 基于 CGLIB 的实现，可以直接代理普通类
4. 使用场景
	需要为 Spring Bean 创建代理以实现切面功能时
	在运行时动态生成代理对象以拦截方法调用
	实现 AOP 功能（如事务管理、安全检查、日志记录等）
5. 实际代码应用示例
// 典型的使用流程
ProxyFactory proxyFactory = new ProxyFactory(targetObject);
proxyFactory.addAdvice(myMethodInterceptor);

// 通过 DefaultAopProxyFactory 创建 AopProxy 实例
AopProxyFactory factory = new DefaultAopProxyFactory();
AopProxy aopProxy = factory.createAopProxy(proxyFactory);

// 获取代理对象
Object proxy = aopProxy.getProxy();

 */
public interface AopProxy {

	/**
	 * Create a new proxy object.
	 * <p>Uses the AopProxy's default class loader (if necessary for proxy creation):
	 * usually, the thread context class loader.
	 * @return the new proxy object (never {@code null})
	 * @see Thread#getContextClassLoader()
	 */
	Object getProxy();

	/**
	 * Create a new proxy object.
	 * <p>Uses the given class loader (if necessary for proxy creation).
	 * {@code null} will simply be passed down and thus lead to the low-level
	 * proxy facility's default, which is usually different from the default chosen
	 * by the AopProxy implementation's {@link #getProxy()} method.
	 * @param classLoader the class loader to create the proxy with
	 * (or {@code null} for the low-level proxy facility's default)
	 * @return the new proxy object (never {@code null})
	 */
	Object getProxy(@Nullable ClassLoader classLoader);

}
